package core;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;
import java.sql.Date;
import java.sql.Time;


import data.DBManager;
import data.Security;
import values.*;

import exception.ServerDownException;

/**
 * Manages proyect logic functions
 */
public class Core 
{
	// Constants
	/**
	 * Properties file path.
	 */
	private static final String CONFIG = "/opt/tomcat/webapps/gente/data/config.properties";
	
	/**
	 * Properties name, images path.
	 */
	private static final String PATH = "path";
	
	// Attributes
	/**
	 * Properties file.
	 */
	private static Properties config;
	
	/**
	 * Data base manager.
	 */
	private static DBManager dbm;
	
	/**
	 * Bank's Class
	 */
	private static Banks banks;
	
	/**
	 * Topic's Class.
	 */
	private static Topics topics;
	
	// Methods
	
	
	public static Topics topic() throws ServerDownException
	{
		if(topics == null)
		{
			topics= new Topics();
		}
		return topics;
	}
	
	
	/**
	 * Load the class Banks
	 */
	public static Banks bank() throws ServerDownException
	{
		if(banks == null)
		{
			banks= new Banks();
		}
		return banks;
	}
	
	
	/**
	 * Load data base manager.
	 */
	private static DBManager DBM() throws ServerDownException
	{
		try
		{
			if(dbm == null)
			{
				if(config == null)
				{
					config = new Properties();
					config.load(new FileInputStream(CONFIG));
				}
				
				dbm = new DBManager(config);
			}
			
			return dbm;
		}
		catch(IOException ioe)
		{
			throw new ServerDownException(ioe.getLocalizedMessage());
		}
	}
	
	/**
	 * Return photos directory.
	 */
	public static String getPath() throws ServerDownException
	{
		try
		{
			if(config == null)
			{
				config = new Properties();
				config.load(new FileInputStream(CONFIG));
			}
			
			return config.getProperty(PATH);
		}
		catch(IOException ioe)
		{
			throw new ServerDownException(ioe.getLocalizedMessage());
		}
	}
	
	/**
	 * Authenticates a user given his credencials.
	 */
	public static User authenticateUser(String login, String password) throws ServerDownException
	{
		login = Security.sanitize(login);
		password = Security.sanitize(password);
		
		return DBM().login(login, password);
	}
	
	/**
	 * Checks the availability of a given login. 
	 */
	public static boolean checkLogin(String login) throws ServerDownException
	{
		login = Security.sanitize(login);
		
		return DBM().verifyLogAv(login);
	}
	
	/**
	 * Checks the availability of a given alias. 
	 */
	public static boolean checkAlias(String alias) throws ServerDownException
	{
		alias = Security.sanitize(alias);
		
		return DBM().verifyAliasAv(alias);
	}
	
	/**
	 * Registers a new user into the data base.
	 */
	public static void registerUser(String login, String password, String alias, String firstName, String lastName, String photo) throws ServerDownException
	{
		login = Security.sanitize(login);
		password = Security.sanitize(password);
		alias = Security.sanitize(alias);
		firstName = Security.sanitize(firstName);
		lastName = Security.sanitize(lastName);
		photo = Security.sanitize(photo);
		
		DBM().SignUpUser(login, password, alias, firstName, lastName, photo);
	}
	
	
	/**
	 * Inserts a comment into the data base.
	 * @throws ServerDownException 
	 */
	public static  void insertComment(String login, String comment, String header) throws ServerDownException
	{	
		comment = Security.sanitize(comment);
		header = header.length() > 140? header.substring(0, 140): header;
		header = Security.sanitize(header);
		
		String[] words = header.split(" ");
		
		ArrayList<String> banks = new ArrayList<String>();
		ArrayList<String> topics = new ArrayList<String>();
		
		for(String word: words)
		{
			if(word.startsWith("@"))
				banks.add(word);
			else if(word.startsWith("#"))
				topics.add(word);
		}
		
		// Borrar lo que sigue.
		
		String b = "";
		
		for(String w: banks)
		{
			b += w + " ";
		}
		
		String t = "";
		
		for(String w: topics)
		{
			t += w + " ";
		}
		
		System.out.println("El comment: " + comment + "\n" +
							"El header: " + header + "\n" +
							"Los bancos: " + b + "\n" + 
							"Los topics: " + t);
	}
	
	/**
	 * Inserts a comment into the data base.
	 * @throws ServerDownException 
	 */
	public static void insertRelatedComment(int parentCommentId, String login, String content) throws ServerDownException
	{
		content = Security.sanitize(content);
		
		java.util.Date utilDate = new java.util.Date();
		
		//Current Date in Milisenconds
		long lnMilisegundos = utilDate.getTime();
		
		//Date convertion to SQL Format.
		Date sqlDate = new Date(lnMilisegundos);
		Time sqlTime = new Time(lnMilisegundos);
		
		DBM().insertRelatedComment(parentCommentId, login, content, sqlDate, sqlTime);
	}
	
	/**
	 * Gets the banks from the data base.
	 * @throws ServerDownException 
	 */
	public static ArrayList<Bank> getBanks() throws ServerDownException
	{
		
		return DBM().getBanks();
	}
	
	public static ArrayList<Topic> getTopics() throws ServerDownException
	{
		return DBM().getTopics();
	}
	

	
	/**
	 * Get the top 5 most recent comments.
	 */
	public static ArrayList<Comment> getRecentComments() throws ServerDownException
	{

		return DBM().getRecentComments();
	}
	
	
	/**
	 * Get the bank's name, matching the given id.
	 */
	public static String getBank(String id) throws ServerDownException
	{
		id = Security.sanitize(id);
		
		return DBM().getBank(id);
	}
	
	/**
	 * Get the user's simplified info associated with the given login.
	 */
	public static User getSimpleUser(String logIn) throws ServerDownException
	{
		logIn = Security.sanitize(logIn);
		
		return DBM().getUser(logIn);
	}
	
	/**
	 * Report a comment as inappropriate.
	 */
	public static void report(int commentId, String user) throws ServerDownException
	{
		System.out.println("entra");
		if(!DBM().getLoginInappropiate(commentId))
			DBM().markCommentAsInappropiate(commentId, user);
	}
	
	/**
	 * Mark a comment as helpful. Only one vote per user. 
	 */
	public static void helpful(int commentId, String user) throws ServerDownException
	{
		if(!DBM().getLoginHelpful(user, commentId))
			DBM().markCommentAsHelpful(commentId, user);
	}
	
	/**
	 * Return true if the given user already voted as helpful the given comment.
	 */
	public static boolean markedHelpful(String user, int comment) throws ServerDownException
	{
		return DBM().getLoginHelpful(user, comment);
	}
	
	/**
	 * Get a comment by it's id.
	 */
	public static Comment getComment(int id) throws ServerDownException
	{
		return DBM().getCommentInfo(id);
	}
	
}
